package com.freemodbus4j.core.codec.tcp;

import com.freemodbus4j.core.codec.AbstractModbusCodec;
import com.freemodbus4j.core.exception.ModbusSlaveCodeEnum;
import com.freemodbus4j.core.frame.TcpFrame;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TcpModbusCodec extends AbstractModbusCodec<TcpFrame.Request, TcpFrame.Response> {

    public TcpFrame.Request decode(ByteBuf in) {
        int readLenght = in.readableBytes();
        in.resetReaderIndex();
        TcpFrame.Request request = TcpFrame.Request.builder()
                .header(TcpFrame.TcpHeader.builder()
                        .transactionId(in.readShort())
                        .protocolId(in.readShort())
                        .length(in.readShort())
                        .unitId(in.readByte())
                        .build())
                .body(super.body(in))
                .build();
        if (request.getBody() == null) {
            TcpFrame.Except except = TcpFrame.Except.builder()
                    .func((byte)(request.getBody().getFunc() | 0x80))
                    .exceptCode(ModbusSlaveCodeEnum.EXCEPT_01)
                    .build();
            request.setExcept(except);
        }
        request.setReadLength(readLenght);
        return request;
    }

    public void encode(TcpFrame.Response response, ByteBuf out) {
        if (response.getExcept() == null) {
            out.writeBytes(response.getHeader().getHeaderBytes());
            super.body(response.getBody(), out);
        } else {
            //异常信息处理
            out.writeBytes(response.getHeader().getHeaderBytes());
            out.writeByte(response.getExcept().getFunc());
            out.writeByte(response.getExcept().getExceptCode().getCode());
        }
    }

}

